package com.hanserwei.community.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hanserwei.community.entity.po.Building;
import com.hanserwei.community.entity.po.House;
import com.hanserwei.community.entity.request.house.HouseAddRequest;
import com.hanserwei.community.entity.request.house.HouseQueryRequest;
import com.hanserwei.community.entity.vo.HouseVO;
import com.hanserwei.community.enums.ResponseCodeEnum;
import com.hanserwei.community.mapper.HouseMapper;
import com.hanserwei.community.service.BuildingService;
import com.hanserwei.community.service.HouseService;
import com.hanserwei.community.uitils.ThrowUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service
public class HouseServiceImpl extends ServiceImpl<HouseMapper, House> implements HouseService {
    private final BuildingService buildingService;

    public HouseServiceImpl(BuildingService buildingService) {
        this.buildingService = buildingService;
    }

    @Override
    public Page<HouseVO> queryHouseByPage(HouseQueryRequest request) {
        Page<House> page = new Page<>(request.getCurrent(), request.getPageSize());
        QueryWrapper<House> queryWrapper = this.getQueryWrapper(request);
        Page<House> housePage = page(page, queryWrapper);
        ThrowUtils.throwIf(housePage == null, ResponseCodeEnum.INVALID_PARAMETER, "查询失败！检查参数！");
        
        List<HouseVO> houseVOList = getHouseVOList(housePage.getRecords());
        Page<HouseVO> houseVOPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        houseVOPage.setRecords(houseVOList);
        return houseVOPage;
    }

    @Override
    public QueryWrapper<House> getQueryWrapper(HouseQueryRequest request) {
        Integer id = request.getId();
        Integer storey = request.getStorey();
        String numbers = request.getNumbers();
        Integer status = request.getStatus();
        LocalDateTime intoDateStart = request.getIntoDateStart();
        LocalDateTime intoDateEnd = request.getIntoDateEnd();
        Integer buildingId = request.getBuildingId();
        String remarks = request.getRemarks();
        BigDecimal areaMin = request.getAreaMin();
        BigDecimal areaMax = request.getAreaMax();
        String sortField = request.getSortField();
        String sortOrder = request.getSortOrder();

        QueryWrapper<House> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null && id > 0, "id", id);
        queryWrapper.eq(storey != null, "storey", storey);
        queryWrapper.like(numbers != null, "numbers", numbers);
        queryWrapper.eq(status != null, "`status`", status);
        queryWrapper.ge(intoDateStart != null, "into_date", intoDateStart);
        queryWrapper.le(intoDateEnd != null, "into_date", intoDateEnd);
        queryWrapper.eq(buildingId != null && buildingId > 0, "building_id", buildingId);
        queryWrapper.like(remarks != null, "remarks", remarks);
        queryWrapper.ge(areaMin != null, "area", areaMin);
        queryWrapper.le(areaMax != null, "area", areaMax);
        queryWrapper.orderBy(sortField != null, !Objects.equals(sortOrder, "descend"), sortField);
        return queryWrapper;
    }

    @Override
    public Page<HouseVO> listByPage(Integer currentNumber, Integer pageSize) {
        Page<House> page = new Page<>(currentNumber, pageSize);
        Page<House> housePage = page(page, null);
        ThrowUtils.throwIf(housePage == null, ResponseCodeEnum.INVALID_PARAMETER, "查询失败！检查参数！");
        
        List<HouseVO> houseVOList = getHouseVOList(housePage.getRecords());
        Page<HouseVO> houseVOPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        houseVOPage.setRecords(houseVOList);
        return houseVOPage;
    }

    @Override
    public boolean addHouse(HouseAddRequest request) {
        House house = new House();
        BeanUtils.copyProperties(request, house);
        
        // 验证建筑物是否存在
        if (request.getBuildingId() != null) {
            Building building = buildingService.getById(request.getBuildingId());
            ThrowUtils.throwIf(building == null, ResponseCodeEnum.INVALID_PARAMETER, "所属建筑物不存在！");
        }
        
        boolean result = save(house);
        ThrowUtils.throwIf(!result, ResponseCodeEnum.SYSTEM_ERROR, "添加失败！");
        return true;
    }

    @Override
    public boolean updateHouse(HouseAddRequest request, Integer id) {
        ThrowUtils.throwIf(request == null, ResponseCodeEnum.INVALID_PARAMETER, "参数错误！");
        ThrowUtils.throwIf(id == null || id <= 0, ResponseCodeEnum.INVALID_PARAMETER, "参数错误！");
        
        // 查询是否存在
        House house = getById(id);
        ThrowUtils.throwIf(house == null, ResponseCodeEnum.INVALID_PARAMETER, "房屋不存在！");
        
        // 验证建筑物是否存在
        if (request.getBuildingId() != null) {
            Building building = buildingService.getById(request.getBuildingId());
            ThrowUtils.throwIf(building == null, ResponseCodeEnum.INVALID_PARAMETER, "所属建筑物不存在！");
        }
        
        BeanUtils.copyProperties(request, house);
        boolean result = updateById(house);
        ThrowUtils.throwIf(!result, ResponseCodeEnum.SYSTEM_ERROR, "更新失败！");
        return true;
    }

    @Override
    public List<HouseVO> getHousesByBuildingId(Integer buildingId) {
        ThrowUtils.throwIf(buildingId == null || buildingId <= 0, ResponseCodeEnum.INVALID_PARAMETER, "建筑物ID参数错误！");
        
        QueryWrapper<House> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("building_id", buildingId);
        List<House> houseList = list(queryWrapper);
        return getHouseVOList(houseList);
    }

    @Override
    public HouseVO getHouseVO(House house) {
        HouseVO houseVO = new HouseVO();
        BeanUtils.copyProperties(house, houseVO);
        Building building = buildingService.getById(house.getBuildingId());
        houseVO.setBuilding(building);
        return houseVO;
    }

    @Override
    public List<HouseVO> getHouseVOList(List<House> houseList) {
        if (houseList == null || houseList.isEmpty()) {
            return List.of();
        }
        
        List<Integer> buildingIds = houseList.stream()
                .map(House::getBuildingId)
                .filter(Objects::nonNull)
                .distinct()
                .toList();
        
        List<Building> buildingList = buildingService.listByIds(buildingIds);
        
        return houseList.stream().map(house -> {
            HouseVO houseVO = new HouseVO();
            BeanUtils.copyProperties(house, houseVO);
            Building building = buildingList.stream()
                    .filter(b -> b.getId().equals(house.getBuildingId()))
                    .findFirst()
                    .orElse(null);
            houseVO.setBuilding(building);
            return houseVO;
        }).toList();
    }
}
